package cn.lili.modules.grab.aop.respose;

import cn.lili.common.exception.ServiceException;
import cn.lili.common.utils.StringUtils;
import cn.lili.exchange.AmqpExchangeProperties;
import cn.lili.modules.grab.dingdong.base.BaseResult;
import cn.lili.modules.grab.dingdong.config.DingdongConfig;
import cn.lili.modules.grab.dingdong.reps.order.CreateOrderRespose;
import cn.lili.modules.grab.dingdong.res.notice.OrderCallbackRequest;
import cn.lili.modules.grab.dingdong.res.order.CreateOrderRequest;
import cn.lili.modules.system.constants.RequestLogTypeConstant;
import cn.lili.modules.system.entity.dos.RequestLog;
import cn.lili.modules.system.entity.dos.ResponseLog;
import cn.lili.routing.ThirdCallLogKey;
import cn.lili.util.AmqpMessage;
import cn.lili.util.AmqpSender;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 第三方请求日志注解注解
 *
 * @author Chopper
 */
@Aspect
@Slf4j
@Component
public class ResponseLogAnntionAop {

    @Resource
    private DingdongConfig dingdongConfig;
    @Resource
    private AmqpSender amqpSender;
    @Resource
    private AmqpExchangeProperties amqpExchangeProperties;

    @Around("@annotation(cn.lili.modules.grab.aop.respose.ResponseLogAnntion)")
    public Object interceptor(ProceedingJoinPoint joinPoint) {
        ResponseLog responseLog = new ResponseLog();
        try {
            //获取请求参数
            Object[] args = joinPoint.getArgs();
            responseLog.setQueryString(JSONObject.toJSONString(args[0]));

            //获取注解参数
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            ResponseLogAnntion requestLogAnntion = method.getAnnotation(ResponseLogAnntion.class);
            String type = requestLogAnntion.type();
            String typeName = requestLogAnntion.typeName();
            responseLog.setType(type);
            responseLog.setTypeName(typeName);

            //获取相应参数
            Object result = joinPoint.proceed();
            responseLog.setResponse(JSONObject.toJSONString(result));
            return result;
        } catch (Throwable e) {
            if(e instanceof ServiceException){
                ServiceException serviceException = (ServiceException) e;
                responseLog.setResponse(serviceException.getMsg());
                throw  serviceException;
            }else{
                throw new RuntimeException();
            }
        } finally {
            //构建请求日志
            builderRequest(responseLog);
            //构建返回日志
            builderRespose(responseLog);
            //发送日志请求
            amqpSender.send(
                    AmqpMessage.builder()
                            .exchange(amqpExchangeProperties.getMsg())
                            .routingKey(ThirdCallLogKey.RESPONSE_LOG)
                            .message(responseLog)
                            .build());
        }
    }

    /**
     * 构建请求日志
     */
    public void builderRequest(ResponseLog responseLog) {
        if (RequestLogTypeConstant.QI_DING_DONG_CREATE_ORDER_CALLBACK.equals(responseLog.getType())) {
            OrderCallbackRequest orderCallbackRequest = JSONObject.parseObject(responseLog.getQueryString(), OrderCallbackRequest.class);
            if(Objects.isNull(responseLog.getItemTaskId())){
                responseLog.setItemTaskId(orderCallbackRequest.getTrade_no());
            }
        }
    }

    /**
     * 构建返回日志
     */
    public void builderRespose(ResponseLog responseLog) {
        //如果为企叮咚创建订单请求
        if (RequestLogTypeConstant.QI_DING_DONG_CREATE_ORDER_CALLBACK.equals(responseLog.getType())) {
            BaseResult baseResult = JSONObject.parseObject(responseLog.getResponse(), BaseResult.class);
            responseLog.setStatusCode(baseResult.getStatus());
            responseLog.setUrl(dingdongConfig.getCallbackOrder());
        }
    }
}